

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Set数据结构</title>
</head>
<body>
    Set类型
    <!-- 
        ES6 提供了新的数据结构 Set。它类似于数组（不能通过下标取值），但是成员的值都是唯一的，没有重复的值.
        语法：new Set()  class是构造函数的语法糖    构造函数和普通函数区别？调用方式不同 定义函数名字命名 返回值
        注意事项：
            1.不能通过下标取值
            2.不能使用for in 循环key 可以使用for of 
        属性和方法：
            - size       获取set集合的长度，注意size是属性不是方法
            - add(值)    给集合添加值，返回新set
            - delete(值) 删除某个值，返回布尔值，表示是否删除成功
            - has(值)    查询这个值是否时集合的成员，返回布尔值
            - clear()    清空集合,没有返回值
        应用场景：
            数组去重
                普通数组
                常见对象数组
            集合运算（并集  交集  差集 ）
     -->
    <script>

        // 1. 语法：new Set() 构造函数
        // 1.1基本使用

        let s = new Set([1,2,3,4,5,3,5])
        console.log(s);
        
        // 1.2伪数组转换成真正的数组 [...]  Array.from()
        let arr = [1,2,3,4,5,3,5,4]
        // let arr2 = Array.from(new Set(arr))
        // console.log(arr2);
        // let arr3 =  [...new Set(arr)]
        // console.log(arr3);


         // 1.3注意事项
        // 1.不能通过下标取值

        // console.log(s[0]);
        // for (const key in arr) {
        //     console.log(arr[key]);   
        // }
        
        for (const k of s) {
            console.log(k);
            
        }
        
        // 3.属性和方法：
        // - 属性：size   获取set集合的长度
        console.log(s.size)
        // - add(值)    给集合添加值，返回新set
        console.log(s.add(10))//{1, 2, 3, 4,5, 10}
        // - delete(值) 删除某个值，返回布尔值，表示是否删除成功
        console.log(s.delete(2))//true
        // - has(值)    查询这个值是否是集合的成员，返回布尔值
        console.log(s.has(3))//true
        // - clear()   清空集合,没有返回值
        console.log(s.clear())//undefined




        // 应用场景：
        // 数组去重

        // function unique(arr) {
        //     return Array.from(new Set(arr))
        // }
        // function unique2(arr) {
        //     return  [...new Set(arr)]
        // }
        // console.log(unique(arr));
        // console.log(unique2(arr));


        //4.1.2常见对象数组(Set) 基本类型比较铭感<===引用类型无法处理
        let userInfo = [
            { id: 1, name: "鲁班", work: "射手" },
            { id: 2, name: "韩信", work: "打野" },
            { id: 1, name: "鲁班", work: "射手" }
        ]

         /* 
        实现思路
            1.要将数组中的每一项值转换成能够被Set识别处理的js数据类型（基本类型==>string）
            2.使用Set对处理后的每一项字符串进行去重
            3.再次遍历去重后的新数组，将每一项字符串数据转换成对象格式
        */

        userInfo = [...new Set(userInfo.map(item => JSON.stringify(item)))] 
        //将处理好的伪数组转换成真正数组
        // userInfo = [...new Set(userInfo)]
        userInfo = userInfo.map(item => JSON.parse(item))
        console.log(userInfo);


        // 集合运算（并集  交集  差集 ）
        let u1 = ['刘德华', '张学友', '郭富城', '黎明']
        let u2 = ['周杰伦', '刘德华', '谢霆锋', '郭富城']
        
        // 1.关注明星并集
        let res = [...new Set([...u1,...u2])]
        console.log(res);
        
        // 2.关注明星交集  技术点：filter + set 
        let s2 = new Set(u1) //首先将u1转化成集合，通过集合中的has方法检测u2中的元素是否存在u1中
        let j = u2.filter(item=>{
            if (s2.has(item)) {
                return item
            }
        })

        console.log(j);

        // 3.关注明星差集  u2相对于u1的   2  技术点：filter + set
        
        let c = u2.filter(item=>{
            if (!s2.has(item)) {
                return item
            }
        })

        console.log(c);
        


    </script>
</body>
</html>